from flask import Blueprint, render_template, abort, redirect, request, session, url_for,current_app,flash
from urllib.parse import quote_plus
from flask_login import login_user, logout_user, login_required, current_user
from werkzeug.security import generate_password_hash, check_password_hash

from app.models import Category, Product, Banner, CategoryI18n, CategorySlugAlias, CustomerUser, BuyClick
from flask_babel import gettext as _, get_locale
from sqlalchemy.orm import joinedload
from app.extensions import db
from app.forms import RegisterForm, LoginForm, ProfileForm

bp = Blueprint('front', __name__)


NAV = [
    ('首页', '/'),
    ('玉镯', '/c/yuzhuo'),
    ('吊坠挂饰', '/c/diaozhui-guashi'),
    ('手链项链', '/c/shoulian-xianglian'),
    ('戒指扳指', '/c/jiezhi-banzhi'),
    ('耳饰', '/c/ershi'),
    ('联系我们', '/contact'),
]


def _lang_code():
    raw = str(get_locale()) if get_locale() else 'zh'
    return raw.replace('-', '_').split('_')[0].lower()


@bp.route('/lang-now')
def lang_now():
    return f"session_lang={session.get('lang')}, locale={get_locale()}"


@bp.app_context_processor
def inject_nav_categories():
    lang = _lang_code()
    cats = (Category.query.options(joinedload(Category.i18n))
            .order_by(Category.sort_order).all())
    items = []
    for c in cats:
        name = c.name
        for t in c.i18n or []:
            if t.lang and t.lang.lower().startswith(lang):
                name = t.name or c.name
                break
        items.append({
            "name": name,
            "url": url_for('front.category', slug=c.slug)  # 统一指向 /c/<slug>
        })
    return dict(nav_categories=items)


@bp.app_context_processor
def inject_nav():
    return dict(get_locale=get_locale)


@bp.route('/auth/register', methods=['GET', 'POST'])
def register():
    if current_user.is_authenticated:
        next_url = request.args.get('next') or url_for('front.index')
        return redirect(next_url)
    form = RegisterForm()
    if form.validate_on_submit():
        # 唯一性检查
        if CustomerUser.query.filter_by(username=form.username.data).first():
            flash('用户名已被占用', 'warning')
            return render_template('auth/register.html', form=form)
        if CustomerUser.query.filter_by(email=form.email.data).first():
            flash('邮箱已被占用', 'warning')
            return render_template('auth/register.html', form=form)

        user = CustomerUser(
            username=form.username.data,
            email=form.email.data,
            password_hash=generate_password_hash(form.password.data),
            shipping_address=form.shipping_address.data or '',
            recipient_name=form.recipient_name.data.strip(),
            phone=form.phone.data.strip(),
            postal_code=form.postal_code.data.strip()
        )
        db.session.add(user)
        db.session.commit()
        login_user(user, remember=True)

        next_url = request.args.get('next') or url_for('front.index')
        flash('注册成功，已自动登录', 'success')
        return redirect(next_url)
    return render_template('auth/register.html', form=form)


@bp.route('/auth/login', methods=['GET', 'POST'])
def login():
    form = LoginForm()
    if form.validate_on_submit():
        u = CustomerUser.query.filter_by(username=form.username_or_email.data).first()  # 或 email
        if u and check_password_hash(u.password_hash, form.password.data):
            login_user(u)
            return redirect(request.form.get('next') or url_for('front.index'))
        flash('账号或密码错误', 'danger')
    else:
        if request.method == 'POST':
            current_app.logger.warning('front.login validate fail: %s', form.errors)
    return render_template('auth/login.html', form=form,
                           post_url=url_for('front.login'),   # ← 传入自己
                           title='会员登录')


@bp.route('/auth/logout')
def logout():
    logout_user()
    flash('已退出登录', 'info')
    return redirect(url_for('front.index'))


@bp.route('/i18n/<lang>', endpoint='set_lang')
def set_lang(lang):
    allowed = current_app.config.get('LANGUAGES', ['zh', 'en'])
    if lang in allowed:
        session['lang'] = lang
    return redirect(request.referrer or url_for('front.index'))


@bp.route('/')
def index():
    banners = Banner.query.filter_by(is_active=True).order_by(Banner.sort_order).all()

    # 关键：把 en_US / en-GB 等都规范为 'en'
    raw = str(get_locale()) if get_locale() else 'zh'
    lang = raw.replace('-', '_').split('_')[0].lower()

    categories = (Category.query
                  .options(joinedload(Category.i18n))
                  .order_by(Category.sort_order)
                  .all())

    def cat_name_localized(c):
        for t in c.i18n or []:
            # 关键：统一小写比较，并允许前缀匹配（en / en_US）
            if t.lang and t.lang.lower().startswith(lang):
                return t.name
        return c.name  # 回退中文

    # 每个分类取对应语言的名字（无则回退默认 name）
    cat_products = []
    for c in categories:
        name = cat_name_localized(c)
        ps = (Product.query
              .filter_by(category_id=c.id, is_published=True)
              .order_by(Product.created_at.desc())
              .limit(8)
              .all())
        cat_products.append(((c, name), ps))
    return render_template('index.html', banners=banners, cat_products=cat_products)


@bp.route('/c/<slug>')
def category(slug):
    c = Category.query.filter_by(slug=slug).first()
    if not c:
        alias = CategorySlugAlias.query.filter_by(old_slug=slug).first()
        if alias:
            c = alias.category
            # 301 永久跳转到“统一后的”规范 slug
            return redirect(url_for('front.category', slug=c.slug), code=301)
        # 仍然找不到 -> 404
        abort(404)

    lang = str(get_locale()) if get_locale() else 'zh'
    name = c.name
    if lang != 'zh':
        t = CategoryI18n.query.filter_by(category_id=c.id, lang=lang).first()
    if t and t.name:
        name = t.name
    products = Product.query.filter_by(category_id=c.id, is_published=True).order_by(Product.created_at.desc()).all()
    return render_template('category.html', category=c, cat_name=name, products=products, lang=lang)


@bp.route('/p/<int:pid>')
def product_detail(pid):
    p = Product.query.get_or_404(pid)
    lang = str(get_locale()) if get_locale() else 'zh'
    return render_template('product_detail.html', p=p, lang=lang)


@bp.route('/contact_us')
def contact_us():
    return render_template('contact_us.html')


@bp.route('/contact')
@login_required
def contact():
    lang = _lang_code()
    pid = request.args.get('product', type=int)
    p = Product.query.get(pid) if pid else None

    # 标题 / SKU / 链接（允许没有 product，也会生成一个通用文案）
    if p:
        title_local = p.t('title', lang) if hasattr(p, 't') else p.title
        sku = p.sku or f"PID-{p.id}"
        try:
            product_url = url_for('front.product_detail', pid=p.id, _external=True)
        except Exception:
            product_url = request.url_root.rstrip('/')  # 至少给站点根
    else:
        title_local = None
        sku = None
        product_url = request.url_root.rstrip('/')

    # 多语言文案 —— 永远生成，不依赖 p 是否存在
    if lang == 'en':
        subj = f"Inquiry about {title_local or 'Product'}{(' (' + sku + ')') if sku else ''}"
        lines = [
            "Hello, I'm interested in this product.",
            f"Title: {title_local}" if title_local else None,
            f"SKU: {sku}" if sku else None,
            f"Link: {product_url}" if product_url else None,
        ]
        email_label, whatsapp_label, wechat_label, copy_label = "Email", "WhatsApp", "WeChat", "Copy inquiry"
    else:
        subj = f"咨询商品：{title_local or '商品'}{('（' + sku + '）') if sku else ''}"
        lines = [
            "你好，我想咨询这件商品。",
            f"标题：{title_local}" if title_local else None,
            f"编号：{sku}" if sku else None,
            f"链接：{product_url}" if product_url else None,
        ]
        email_label, whatsapp_label, wechat_label, copy_label = "邮箱", "WhatsApp", "微信", "复制咨询内容"

    body = "\n".join([L for L in lines if L])  # ← 即使没有 product 也不为空

    # 配置
    email_to = current_app.config.get('CONTACT_EMAIL') or ''
    whats = current_app.config.get('WHATS_NUMBER') or ''
    kf_url = current_app.config.get('WECHAT_KF_URL') or ''
    qr_rel = current_app.config.get('WECHAT_QR_PATH', 'images/wechat_qr.jpg')

    # 生成链接
    mailto = f"mailto:{email_to}?subject={quote_plus(subj)}&body={quote_plus(body)}" if email_to else None
    wa = f"https://wa.me/{whats}?text={quote_plus(body)}" if whats else None

    # 用 url_for 保证二维码一定能显示（必须放在 static/ 下）
    qr_url = url_for('static', filename=qr_rel)

    return render_template(
        'contact.html',
        p=p,
        subj=subj,
        body=body,
        mailto=mailto,
        wa=wa,
        kf_url=kf_url,
        qr_url=qr_url,  # ← 传给模板
        email_label=email_label,
        whatsapp_label=whatsapp_label,
        wechat_label=wechat_label,
        copy_label=copy_label,
    )


@bp.route('/checkout/<int:pid>')
@login_required
def checkout(pid):
    """单品立即购买入口：只做校验，然后跳到 /shop/checkout/confirm"""
    p = Product.query.get_or_404(pid)

    # 库存校验（有 stock 字段的话）
    if getattr(p, "stock", None) is not None and p.stock <= 0:
        flash(_('该商品已售罄'), 'warning')
        # 按你的详情页路由改：如果是 front.product_detail(slug)
        return redirect(url_for('front.product_detail', slug=p.slug or p.id))

    # 数量先写死 1，有需要再在确认页改数量
    return redirect(url_for('shop.checkout_confirm', pid=p.id, qty=1))


@bp.route('/account/profile', methods=['GET', 'POST'])
@login_required
def account_profile():
    # 仅允许客户用户（如你同时有 AdminUser）
    if not isinstance(current_user, CustomerUser):
        flash(_("Only customer users have a profile page."), "warning")
        return redirect(url_for('front.index'))

    form = ProfileForm(obj=current_user)
    if form.validate_on_submit():
        # 用户名/邮箱唯一检查（如果改了）
        if form.username.data != current_user.username:
            exists = CustomerUser.query.filter_by(username=form.username.data).first()
            if exists:
                form.username.errors.append(_("Username already exists"))
                return render_template('account_profile.html', form=form)

        if form.email.data != current_user.email:
            exists = CustomerUser.query.filter_by(email=form.email.data).first()
            if exists:
                form.email.errors.append(_("Email already exists"))
                return render_template('account_profile.html', form=form)

        current_user.username = form.username.data
        current_user.email = form.email.data
        current_user.recipient_name = form.recipient_name.data
        current_user.phone = form.phone.data
        current_user.postal_code = form.postal_code.data
        current_user.shipping_address = form.shipping_address.data
        db.session.commit()
        flash(_("Profile updated"), "success")
        # 返回到 next 或个人页
        return redirect(request.args.get('next') or url_for('front.account_profile'))

    return render_template('account_profile.html', form=form)


@bp.route('/track/buy_click')
def track_buy_click():
    product_id = request.args.get('pid', type=int)
    channel = (request.args.get('ch') or 'direct').lower()  # direct/email/whatsapp/wechat
    next_url = request.args.get('next') or url_for('front.index')

    if product_id:
        try:
            evt = BuyClick(
                user_id=current_user.id if getattr(current_user, 'is_authenticated', False) else None,
                product_id=product_id,
                channel=channel
            )
            db.session.add(evt)
            db.session.commit()
        except Exception:
            db.session.rollback()
    return redirect(next_url)